package de.homelabs.moonrat.template.freemarker;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import de.homelabs.moonrat.context.DataProviderService;
import de.homelabs.moonrat.context.IDataProvider;
import de.homelabs.moonrat.context.plugin.template.ITemplateDataProvider;
import de.homelabs.moonrat.exception.MoonratException;
import de.homelabs.moonrat.template.MoonratTemplate;
import freemarker.cache.TemplateLoader;

@Service
public class MoonratFreemarkerTemplateLoader implements TemplateLoader {

	@Autowired
	private DataProviderService dataProviderService;
	
	private List<ITemplateDataProvider> templateDataProviders = new ArrayList<ITemplateDataProvider>();
	
	private Logger logger = Logger.getLogger(MoonratFreemarkerTemplateLoader.class);
	
	public Object findTemplateSource(String name) throws IOException {
		//try every TemplateProvider, first one wins
		MoonratTemplate moonratTemplate = null;
		for (ITemplateDataProvider templateDataProvider : templateDataProviders){
			try {
				moonratTemplate = templateDataProvider.getTemplate(name);
				if (moonratTemplate != null){
					//template found, nothing more to do
					//know your dataprovider!
					moonratTemplate.setDataProvider(templateDataProvider);
					return moonratTemplate;
				}
			} catch (MoonratException e) {
				//Freemarker does not know about HLTemplateException
				throw new IOException(e.toString());
			}
		}
		
		//nothing found
		return null;
	}

	public long getLastModified(Object template) {
		if (template != null && template instanceof MoonratTemplate){
			MoonratTemplate moonratTemplate = (MoonratTemplate) template;
			
			//get template filestamp
			try {
				return moonratTemplate.getDataProvider().getTemplateLastModified((MoonratTemplate) template);
			} catch (MoonratException e) {
				return 0L;
			}
		} else {
			//nothing found
			return 0L;
		}
	}

	public Reader getReader(Object template, String encoding)
			throws IOException {
		
		if (template != null && template instanceof MoonratTemplate){
			MoonratTemplate moonratTemplate = (MoonratTemplate) template;
			
			//get template reader
			try {
				return moonratTemplate.getDataProvider().getTemplateReader((MoonratTemplate) template);
			} catch (MoonratException e) {
				throw new IOException(e);
			}
						
		} else {
			//nothing found
			return null;
		}
	}

	public void closeTemplateSource(Object template) throws IOException {
		if (template != null && template instanceof MoonratTemplate){
			MoonratTemplate moonratTemplate = (MoonratTemplate) template;
			try {
				moonratTemplate.getDataProvider().closeTemplateReader((MoonratTemplate) template);
			} catch (MoonratException e) {
				throw new IOException(e);
			}
		}
	}

	public void initTemplateDataProvider(){
		//list of possible TemplateProvider
		List<IDataProvider> dataProviders = dataProviderService.getDataProviderByProviderKey("template_data_provider");

		for(IDataProvider dataProvider : dataProviders){
			if (dataProvider instanceof ITemplateDataProvider){
				//register TempalteProvider 
				templateDataProviders.add((ITemplateDataProvider) dataProvider);
				logger.debug("register TemplateProvider: "+dataProvider.getClass());
			}
		}
	}
}
